#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

// 定义常量
#define MAX_ORDERS 20        // 最大订单数
#define MAX_DISHES 4         // 菜品数量
#define MAX_USERS 10         // 最大用户数
#define MAX_NAME_LEN 20      // 姓名最大长度
#define MAX_ADDR_LEN 50      // 地址最大长度
#define MAX_DISH_NAME 20     // 菜品名最大长度

// 订单状态枚举
typedef enum {
    ORDERED,     // 已预定
    COMPLETED    // 已完成
} OrderStatus;

// 菜品结构体
typedef struct {
    int id;                  // 菜品编号
    char name[MAX_DISH_NAME];// 菜品名称
    float price;             // 单价
    int likeCount;           // 点赞数
} Dish;

// 订单结构体
typedef struct {
    int id;                  // 订单编号
    char userName[MAX_NAME_LEN];// 订餐人
    char dishName[MAX_DISH_NAME];// 菜品名称
    int quantity;            // 数量
    int deliveryTime;        // 送餐时间（24小时制）
    char address[MAX_ADDR_LEN];// 送餐地址
    float totalPrice;        // 总金额
    OrderStatus status;      // 订单状态
    int userId;              // 关联用户ID(-1表示未登录状态)
} Order;

// 用户结构体
typedef struct {
    int id;                  // 用户ID
    char username[MAX_NAME_LEN];// 用户名
    char password[20];       // 密码
    char phone[12];          // 手机号
    int isAdmin;             // 是否管理员(1是0否)
} User;

// 全局变量
Dish dishes[MAX_DISHES] = {
    {1, "黄焖鸡", 25.0f, 0},
    {2, "鱼香肉丝", 20.0f, 0},
    {3, "麻婆豆腐", 10.0f, 0},
    {4, "清炒土豆丝", 8.0f, 0}
};
Order orders[MAX_ORDERS];   // 订单数组
User users[MAX_USERS];      // 用户数组
int orderCount = 0;         // 当前订单数
int userCount = 0;          // 当前用户数
int currentUserId = -1;     // 当前登录用户ID(-1表示未登录)
int nextOrderId = 1;        // 下一个订单ID

// 函数声明
void initSystem();
void printMenu();
void placeOrder();
void viewOrders();
void signOrder();
void deleteOrder();
void likeDish();
int login();
void registerUser();
void sortDishesByLikes();

// 系统初始化
void initSystem() {
    // 初始化订单数组
    for (int i = 0; i < MAX_ORDERS; i++) {
        orders[i].id = 0;
        orders[i].userId = -1;
    }
    
    // 添加默认管理员
    strcpy(users[0].username, "admin");
    strcpy(users[0].password, "admin123");
    strcpy(users[0].phone, "123456");
    users[0].isAdmin = 1;
    users[0].id = 1;
    userCount = 1;
}

// 打印主菜单
void printMenu() {
    system("cls");
    printf("欢迎使用【吃了吗订餐系统】\n");
    printf("************************\n");
    printf("1、我要订餐\n");
    printf("2、查看餐袋\n");
    printf("3、签收订单\n");
    printf("4、删除订单\n");
    printf("5、我要点赞\n");
    printf("6、用户注册\n");
    printf("7、用户登录\n");
    printf("8、退出系统\n");
    printf("************************\n");
    printf("请选择: ");
}

// 打印菜品列表
void printDishes() {
    printf("序号\t菜名\t单价\t点赞数\n");
    for (int i = 0; i < MAX_DISHES; i++) {
        printf("%d\t%s\t%.1f元\t%d\n", 
               dishes[i].id,
               dishes[i].name,
               dishes[i].price,
               dishes[i].likeCount);
    }
}

// 我要订餐功能
void placeOrder() {
    if (orderCount >= MAX_ORDERS) {
        printf("很抱歉,本店今日菜品已售完,请明日再来。\n");
        printf("输入任意键返回...");
        getchar();
        getchar();
        return;
    }
    
    Order newOrder;
    newOrder.id = nextOrderId++;
    newOrder.status = ORDERED;
    newOrder.userId = currentUserId;
    
    printf("***我要订餐***\n");
    printf("请输入订餐人姓名: ");
    getchar();
    fflush(stdin);
    fgets(newOrder.userName, MAX_NAME_LEN, stdin);
    newOrder.userName[strcspn(newOrder.userName, "\n")] = '\0';  // 去除换行符
    
    // 显示菜品
    printDishes();
    
    int dishId, quantity, time;
    printf("请选择您要点的菜品编号: ");
    scanf("%d", &dishId);
    
    // 验证菜品编号
    if (dishId < 1 || dishId > MAX_DISHES) {
        printf("无效的菜品编号!\n");
        printf("输入任意键返回...");
        getchar();
        getchar();
        return;
    }
    
    printf("请选择您需要的份数: ");
    scanf("%d", &quantity);
    if (quantity <= 0) {
        printf("份数必须为正数!\n");
        printf("输入任意键返回...");
        getchar();
        getchar();
        return;
    }
    
    printf("请输入送餐时间(送餐时间是10点至20点间整点送餐): ");
    scanf("%d", &time);
    if (time < 10 || time > 20) {
        printf("送餐时间必须在10-20点之间!\n");
        printf("输入任意键返回...");
        getchar();
        getchar();
        return;
    }
    
    fflush(stdin);
    printf("请输入送餐地址: ");
    fgets(newOrder.address, MAX_ADDR_LEN, stdin);
    newOrder.address[strcspn(newOrder.address, "\n")] = '\0';
    
    // 计算价格
    strcpy(newOrder.dishName, dishes[dishId-1].name);
    newOrder.quantity = quantity;
    newOrder.deliveryTime = time;
    float dishTotal = dishes[dishId-1].price * quantity;
    float deliveryFee = 5.0f;  // 送餐费固定5元
    newOrder.totalPrice = dishTotal + deliveryFee;
    
    // 保存订单
    orders[orderCount++] = newOrder;
    
    // 显示订单信息
    printf("订餐成功!\n");
    printf("您订的是: %s %d份\n", newOrder.dishName, newOrder.quantity);
    printf("送餐时间: %d时\n", newOrder.deliveryTime);
    printf("餐费: %.1f元, 送餐费5.0元, 总计: %.1f元。\n", dishTotal, newOrder.totalPrice);
    printf("输入A返回: ");
    
    char back;
    getchar();
    scanf("%c", &back);
}

// 查看餐袋功能
void viewOrders() {
    printf("***查看餐袋***\n");
    printf("%-6s %-8s %-15s %-8s %-20s %-8s %-6s\n", 
           "序号", "订餐人", "餐品信息", "送餐时间", "送餐地址", "总金额", "订单状态");
    
    int count = 0;
    for (int i = 0; i < orderCount; i++) {
        // 管理员/员工可以查看所有订单，普通用户只能查看自己的订单
        if (currentUserId == -1 || 
            (users[currentUserId-1].isAdmin) || 
            (orders[i].userId == currentUserId)) {
            
            count++;
            printf("%-6d %-8s %-15s %-8d %-20s %-8.1f %-6s\n",
                   orders[i].id,
                   orders[i].userName,
                   orders[i].dishName,
                   orders[i].deliveryTime,
                   orders[i].address,
                   orders[i].totalPrice,
                   orders[i].status == ORDERED ? "已预定" : "已完成");
        }
    }
    
    if (count == 0) {
        printf("暂无订单信息\n");
    }
    
    printf("输入任意键返回...");
    getchar();
    getchar();
}

// 签收订单功能
void signOrder() {
    printf("***签收订单***\n");
    int orderId;
    printf("请选择要签收的订单序号: ");
    scanf("%d", &orderId);
    
    // 查找订单
    int found = 0;
    for (int i = 0; i < orderCount; i++) {
        if (orders[i].id == orderId) {
            found = 1;
            // 检查订单状态
            if (orders[i].status == COMPLETED) {
                printf("该订单已被签收!\n");
            } else {
                orders[i].status = COMPLETED;
                printf("订单签收成功!\n");
            }
            break;
        }
    }
    
    if (!found) {
        printf("您选择的订单不存在!\n");
    }
    
    printf("输入0返回: ");
    int back;
    scanf("%d", &back);
}

// 删除订单功能
void deleteOrder() {
    printf("***删除订单***\n");
    int orderId;
    printf("请输入要删除的订单序号: ");
    scanf("%d", &orderId);
    
    // 查找订单
    int i, found = 0;
    for (i = 0; i < orderCount; i++) {
        if (orders[i].id == orderId) {
            found = 1;
            break;
        }
    }
    
    if (!found) {
        printf("您要删除的订单不存在!\n");
        printf("输入0返回: ");
        int back;
        scanf("%d", &back);
        return;
    }
    
    // 检查订单状态
    if (orders[i].status == ORDERED) {
        printf("您选择的订单未签收,不能删除!\n");
        printf("输入0返回: ");
        int back;
        scanf("%d", &back);
        return;
    }
    
    // 检查权限（普通用户只能删除自己的订单）
    if (currentUserId != -1 && !users[currentUserId-1].isAdmin && 
        orders[i].userId != currentUserId) {
        printf("您没有权限删除该订单!\n");
        printf("输入0返回: ");
        int back;
        scanf("%d", &back);
        return;
    }
    
    // 执行删除（将后面的订单前移）
    for (int j = i; j < orderCount-1; j++) {
        orders[j] = orders[j+1];
    }
    orderCount--;
    
    printf("删除订单成功!\n");
    printf("输入0返回: ");
    int back;
    scanf("%d", &back);
}

// 按点赞数排序菜品
void sortDishesByLikes() {
    for (int i = 0; i < MAX_DISHES-1; i++) {
        for (int j = 0; j < MAX_DISHES-i-1; j++) {
            if (dishes[j].likeCount < dishes[j+1].likeCount) {
                Dish temp = dishes[j];
                dishes[j] = dishes[j+1];
                dishes[j+1] = temp;
            }
        }
    }
}

// 我要点赞功能
void likeDish() {
    printf("***我要点赞***\n");
    printDishes();
    
    int dishId;
    printf("请选择您要点赞的菜品序号: ");
    scanf("%d", &dishId);
    
    if (dishId < 1 || dishId > MAX_DISHES) {
        printf("无效的菜品编号!\n");
        printf("输入0返回: ");
        int back;
        scanf("%d", &back);
        return;
    }
    
    // 点赞
    dishes[dishId-1].likeCount++;
    printf("点赞成功!\n");
    
    // 排序后显示
    sortDishesByLikes();
    printf("最新点赞排行:\n");
    printDishes();
    
    printf("输入0返回: ");
    int back;
    scanf("%d", &back);
}

// 用户注册功能
void registerUser() {
    if (userCount >= MAX_USERS) {
        printf("注册用户已达上限，无法继续注册!\n");
        printf("输入任意键返回...");
        getchar();
        getchar();
        return;
    }
    
    User newUser;
    newUser.id = userCount + 1;
    newUser.isAdmin = 0;  // 默认为普通用户
    
    printf("***用户注册***\n");
    printf("请输入用户名: ");
    fflush(stdin);
    fgets(newUser.username, MAX_NAME_LEN, stdin);
    newUser.username[strcspn(newUser.username, "\n")] = '\0';
    
    // 检查用户名是否已存在
    for (int i = 0; i < userCount; i++) {
        if (strcmp(users[i].username, newUser.username) == 0) {
            printf("用户名已存在!\n");
            printf("输入任意键返回...");
            getchar();
            return;
        }
    }
    
    printf("请输入密码: ");
    fflush(stdin);
    fgets(newUser.password, 20, stdin);
    newUser.password[strcspn(newUser.password, "\n")] = '\0';
    
    printf("请输入手机号: ");
    fflush(stdin);
    fgets(newUser.phone, 12, stdin);
    newUser.phone[strcspn(newUser.phone, "\n")] = '\0';
    
    // 保存用户信息
    users[userCount++] = newUser;
    printf("注册成功!\n");
    printf("输入任意键返回...");
    getchar();
}

// 用户登录功能
int login() {
    char username[MAX_NAME_LEN];
    char password[20];
    int attempts = 3;
    
    while (attempts > 0) {
        printf("***用户登录***\n");
        printf("请输入用户名: ");
        fflush(stdin);
        fgets(username, MAX_NAME_LEN, stdin);
        username[strcspn(username, "\n")] = '\0';
        
        printf("请输入密码: ");
        fflush(stdin);
        fgets(password, 20, stdin);
        password[strcspn(password, "\n")] = '\0';
        
        // 验证用户名和密码
        for (int i = 0; i < userCount; i++) {
            if (strcmp(users[i].username, username) == 0 && 
                strcmp(users[i].password, password) == 0) {
                printf("登录成功!\n");
                currentUserId = users[i].id;
                printf("输入任意键返回...");
                getchar();
                return 1;
            }
        }
        
        attempts--;
        printf("用户名或密码不正确，还有%d次机会!\n", attempts);
        if (attempts == 0) {
            printf("登录失败次数过多，系统将退出!\n");
            return 0;
        }
    }
    return 1;
}

// 主函数
int main() {
    initSystem();
    int choice;
    int running = 1;
    
    // 登录提示
    printf("是否需要登录? (1-是 0-游客模式): ");
    scanf("%d", &choice);
    if (choice == 1) {
        if (!login()) {
            return 0;  // 登录失败退出
        }
    }
    
    while (running) {
        printMenu();
        scanf("%d", &choice);
        
        switch (choice) {
            case 1:
                placeOrder();
                break;
            case 2:
                viewOrders();
                break;
            case 3:
                signOrder();
                break;
            case 4:
                deleteOrder();
                break;
            case 5:
                likeDish();
                break;
            case 6:
                registerUser();
                break;
            case 7:
                if (currentUserId != -1) {
                    printf("您已登录，如需切换账号，请先退出系统!\n");
                    printf("输入任意键返回...");
                    getchar();
                    getchar();
                } else {
                    if (!login()) {
                        running = 0;  // 登录失败退出系统
                    }
                }
                break;
            case 8:
                running = 0;
                printf("感谢使用【吃了吗订餐系统】，欢迎下次再来!\n");
                break;
            default:
                printf("无效的选择，请重新输入!\n");
                printf("输入任意键返回...");
                getchar();
                getchar();
        }
    }
    
    return 0;
}    